package com.yunyao.framework.audit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunyao.common.constant.enums.AuditStatusEnums;
import com.yunyao.common.constant.enums.DataDeletedStatus;
import com.yunyao.common.constant.enums.SupplyStatus;
import com.yunyao.common.dto.audit.AuditFlowTypeEnums;
import com.yunyao.common.dto.audit.AuditResultEnums;
import com.yunyao.common.dto.audit.CreateAuditFlowDto;
import com.yunyao.common.exception.AuditException;
import com.yunyao.common.web.enums.ResultMsgEnum;
import com.yunyao.common.web.util.ConvertUtil;
import com.yunyao.dao.model.*;
import com.yunyao.dao.service.bamu.*;
import com.yunyao.framework.dto.audit.ApprovalDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 *
 * 收款管理审批Handle
 * @author chenyejian
 * @date 2024-08-01
 */
@Slf4j
@Component
public class ReceiveAuditHandle extends AbstractAuditFlowHandle {
    @Autowired
    private IBamuReceiveService iBamuReceiveService;
    @Autowired
    private IBamuReceiveHistoryService receiveHistoryService;

    @Transactional(rollbackFor = AuditException.class)
    public void submit(String bizId) throws AuditException {
        BamuReceive receive = iBamuReceiveService.getById(bizId);
        String name = receive.getContractName();
        Integer status = receive.getStatus();
        String modelInfoReceiveId = defaultAuditModelInfo.getReceiveId();
        try {
            /**
             * 校验数据
             */
            checkSubmitData(receive);
            CreateAuditFlowDto createAuditFlowDto = creatFlow(modelInfoReceiveId,
                    AuditFlowTypeEnums.MODEL_NAME_RECEIVE.getType(), bizId, name,
                    String.valueOf(status));

            receive.setProcessInstanceId(createAuditFlowDto.getProcessInstanceId());
            receive.setDeploymentId(createAuditFlowDto.getDeploymentId());
            receive.setModelSchemeInfoId(createAuditFlowDto.getModelSchemeInfoId());
            receive.setProcessVersion(createAuditFlowDto.getProcessVersion());
            receive.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT.getType()));
            iBamuReceiveService.saveOrUpdate(receive);
        } catch (Exception e) {
            log.error("收款管理submit approval error", e);
            throw new AuditException(e.getMessage());
        }
    }

    public void approval(ApprovalDto approvalDto) throws AuditException {
        try {
            String bizId = approvalDto.getId();
            Boolean auditResult = approvalDto.getAuditResult();
            String auditResultStr = auditResult ? AuditResultEnums.AGREE.getKey() :
                    AuditResultEnums.REJECT.getKey();
            BamuReceive receive = iBamuReceiveService.getById(bizId);
            checkApprovalData(receive);
            boolean isEnd = executeFlow(receive.getProcessInstanceId(),
                    receive.getDeploymentId(), auditResultStr,
                    approvalDto.getAuditResultMsg(), approvalDto.getAuditFileList());
            if (!isEnd) {
                return;
            }
            if (auditResult) {
                 /**
                 * 保存收款历史记录
                 */
                LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<BamuReceiveHistory>()
                        .eq(BamuReceiveHistory::getReceiveId, receive.getId())
                        .eq(BamuReceiveHistory::getIsDeleted, DataDeletedStatus.NO.getType());
                List<BamuReceiveHistory> historyList = receiveHistoryService.list(queryWrapper);
                if (historyList == null || historyList.size() == 0) {
                    BamuReceiveHistory history = new BamuReceiveHistory();
                    BeanUtils.copyProperties(receive, history);
                    history.setReceiveId(receive.getId());
                    receiveHistoryService.saveOrUpdate(history);
                }
                receive.setAuditStatus(ConvertUtil.null2String(AuditStatusEnums.AUDIT_SUCCESS.getType()));
            } else {
                receive.setAuditStatus(ConvertUtil.null2String(AuditStatusEnums.AUDIT_REJECT.getType()));
            }
            iBamuReceiveService.saveOrUpdate(receive);
        } catch (Exception e) {
            log.error("收款管理 approval error", e);
            throw new AuditException(e.getMessage());
        }

    }

    private void checkApprovalData(BamuReceive approvalData) throws AuditException {
        if (Objects.isNull(approvalData)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }
        String auditStatus = approvalData.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() != Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
        String processInstanceId = approvalData.getProcessInstanceId();
        if (StringUtils.isBlank(processInstanceId)) {
            throw new AuditException("processInstanceId is null");
        }
        String deploymentId = approvalData.getDeploymentId();
        if (StringUtils.isBlank(deploymentId)) {
            throw new AuditException("deploymentId is null");
        }
    }

    public boolean userIsAuditButton(String schemeInfoId, String processInstanceId) {
        try {
            return isCheckAudit(schemeInfoId, processInstanceId);
        } catch (Exception e) {
            log.info("收款管理userIsAuditButton error:{}", e.getMessage());
            return false;
        }
    }

    private void checkSubmitData(BamuReceive receive) throws AuditException {

        if (Objects.isNull(receive)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }

        String auditStatus = receive.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_SUCCESS.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_REJECT.getType() == Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
    }
}
